from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply
from PyQt5.QtNetwork import QNetworkRequest
from PyQt5.QtCore import QUrl
from PyQt5.QtWebKitWidgets import QWebView, QWebPage, QWebFrame
from network.networkutils import *
from network.networkfilter import *
from network.globalfilter import FILTERS

class FilteredPage(QWebPage):
    def acceptNavigationRequest(self, frame: QWebFrame, request: QNetworkRequest, type: 'QWebPage.NavigationType') -> bool:
        try:
            url = request.url()
            url1 = url.toEncoded().data().decode('utf-8')
            domain = getDomain(url1)
            for filter in FILTERS:
                if not filter.allowRequest(makeNetworkObject(url1, domain, None)):
                    print("YAWK: Network: Request blocked by the filter '" + filter.filterName() + "'.\n\tURL: " + url)
                    return False
            return QWebPage.acceptNavigationRequest(self, frame, request, type)
        except Exception as e:
            print(e)
            return QWebPage.acceptNavigationRequest(self, frame, request, type)

    def runJavaScript(self, payload):
        self.currentFrame().evaluateJavaScript(payload)

class FilteredNetworkAccessManager(QNetworkAccessManager):
    def __init__(self, parent=None):
        super().__init__(parent=parent)

    def createRequest(self, operation, request, device):
        url1 = request.url().toEncoded().data().decode('utf-8')
        domain = getDomain(url1)
        for filter in FILTERS:
            if not filter.allowRequest(makeNetworkObject(url1, domain, None)):
                print("YAWK: Network: Request blocked by the filter '" + filter.filterName() + "'.\n\tURL: " + url1)
                return BlockedReply(self, operation, request, device)
        return super().createRequest(operation, request, device)

class BlockedReply(QNetworkReply):
    def __init__(self, parent, operation, request, device):
        super().__init__(parent=parent)
        self.setRequest(request)
        self.setOperation(operation)
        self.setUrl(request.url())
        self.bytes_read = 0
        self.content = b''

    def abort(self) -> None:
        pass
